//
//  HY_LRefreshControl.swift
//  HomeSchoolDemo
//
//  Created by rimi on 16/10/9.
//  Copyright © 2016年 赖虹宇. All rights reserved.
//

import UIKit

//记录临界点
fileprivate let HY_LRefreshOffset : CGFloat = 60
   ///刷新视图状态
enum hy_LRefreshState{
    case nomol    //普通状态
    case pulling   //超过临界点，如果放手就开始刷新
    case willRefresh   //已经超过临界点，并且已经放手，开始准备刷新
}

class HY_LRefreshControl: UIControl {
    //记录父视图
    fileprivate weak var scrollView: UIScrollView?
    //创建UI属性
    var refreshV = HY_LRefreshView.refreshV()
   
    
    init() {
        super.init(frame: CGRect())
        //设置UI
        setUpUI()
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
       setUpUI()
    }
    //获得父类属性
    //这个方法是在执行addSubview 会调用，移除时也会调用
    //KVO添加监听以后必须在当前视图销毁前移除，否则会直接崩溃，不同于通知，通知不移除时不会发生什么。但是会造成内存泄漏或重复添加
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        //判断一下
        guard let sv = newSuperview as? UIScrollView else {
            return
        }
        //记录父视图
        scrollView = sv
        //使用KVO添加父视图属性变化
        sv.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
        
        
    }
    //当前视图移除时会调用此
    override func removeFromSuperview() {
        //移除监听，必须在执行父类方法前
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        super.removeFromSuperview()
        
    }
    //KVO的监听回调方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        guard let sv = scrollView else {
            return
        }
        //获得高度
        let h = -(sv.contentOffset.y + sv.contentInset.top)
        //屏蔽向上滚出屏幕的功能
        if h < 0 {
            return
        }
        //如果是正在拖拽拖拽情况下
        if sv.isDragging {
            
            if h > HY_LRefreshOffset && refreshV.refreshState == .nomol{
                refreshV.refreshState = .pulling
                //没放手状态下返回
            }else if h < HY_LRefreshOffset && refreshV.refreshState == .pulling {
                refreshV.refreshState = .nomol
            }
        }
        else {
            //进入这里表示拖拽结束,如果是超过临界点就开始刷新
            if refreshV.refreshState == .pulling {
//                beginRefreshing()
                //发送事件消息的系统方法
                sendActions(for: .valueChanged)
            }
            
        }
       //设置控件高度
        self.frame = CGRect(x: 0,
                            y: -h,
                            width: UIScreen.main.bounds.width,
                            height: h)
    }
    
    
   ///开始刷新
    func beginRefreshing(){
        guard let sv = scrollView  else {
            return
        }
        //避免重复刷新过程
        if refreshV.refreshState == .willRefresh {
            return
        }
        //已经进入刷新数据状态
        refreshV.refreshState = .willRefresh
        //保持刷新状态视图，
        var inset = sv.contentInset
        inset.top += HY_LRefreshOffset
        sv.contentInset = inset

    }
    
   ///结束刷新
    func endRefreshing(){
        guard let sv = scrollView else {
            return
        }
        //避免重复刷新过程
        if refreshV.refreshState != .willRefresh {
            return
        }
        //调整父视图高度-并有个动画过程
        UIView.animate(withDuration: 0.25, animations: {
            var inset = sv.contentInset
            inset.top -= HY_LRefreshOffset
            sv.contentInset = inset
            }) { (_) in
                //修改状态
                self.refreshV.refreshState = .nomol
        }
    }
    
}
extension HY_LRefreshControl{
    // fileprivate 私有的
   fileprivate func setUpUI(){
   
    //添加视图
    addSubview(refreshV)
            
    //裁剪超出边界的内容
//    clipsToBounds = true
    
    //使用原生的约束框架，必须先关掉系统的自动设置约束的属性
    //storyboard会自动关闭，纯代码需手动设置下面这个属性为false
    refreshV.translatesAutoresizingMaskIntoConstraints = false
    //设置 中心x
    addConstraint(NSLayoutConstraint(item: refreshV,
                                     attribute: .centerX,
                                     relatedBy: .equal,
                                     toItem: self,
                                     attribute: .centerX,
                                     multiplier: 1.0,
                                     constant: 0))
    //设置中心y
    addConstraint(NSLayoutConstraint(item: refreshV,
                                     attribute: .bottom,
                                     relatedBy: .equal,
                                     toItem: self,
                                     attribute: .bottom,
                                     multiplier: 1.0,
                                     constant: 0))
    //设置宽
    addConstraint(NSLayoutConstraint(item: refreshV,
                                     attribute: .width,
                                     relatedBy: .equal,
                                     toItem: nil,
                                     attribute: .notAnAttribute,
                                     multiplier: 1.0,
                                     constant: refreshV.bounds.width))
    //设置高
    addConstraint(NSLayoutConstraint(item: refreshV,
                                     attribute: .height,
                                     relatedBy: .equal,
                                     toItem: nil,
                                     attribute: .notAnAttribute,
                                     multiplier: 1.0,
                                     constant: refreshV.bounds.height))
    
    }
}
